package com.test.shop.product.web;

import com.test.shop.product.entity.CategoryEntity;
import com.test.shop.product.service.CategoryService;
import com.test.shop.product.vo.Catelog2Vo;
import jodd.time.TimeUtil;
import org.redisson.api.*;
import org.redisson.client.RedisClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * @date 2021/12/25 -22:41
 */
@Controller
public class IndexController {

    @Autowired
    private CategoryService categoryService;

    @Autowired
    private RedissonClient redissonClient;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @GetMapping({"/","/index.html"})
    public String indexPage(Model model){
        // 查出一级分类
        List<CategoryEntity> categoryEntityList = categoryService.getLevelCategorys();
        model.addAttribute("categorys",categoryEntityList);
        return "index";
    }

    @ResponseBody
    @GetMapping("/index/catalog.json")
    public Map<String,List<Catelog2Vo>> getCatalogJson(){

        Map<String,List<Catelog2Vo>> map = categoryService.getCatalogJson();
        return map;
    }

    @ResponseBody
    @GetMapping("/test/redis")
    public String test(){
        // 如果锁名称相同即表示一把锁
        RLock lock = redissonClient.getLock("myLock");
        // 加锁
        lock.lock(10, TimeUnit.SECONDS);
        try{
            System.out.println("执行业务:..."+Thread.currentThread().getName());
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            System.out.println("解锁...:"+Thread.currentThread().getName());
            lock.unlock();
        }
        return "lock";
    }

    @ResponseBody
    @GetMapping("/write")
    public String writeValue(){
        RReadWriteLock lock = redissonClient.getReadWriteLock("rw-lock");
        String s = "";
        // 读写锁即改数据加写锁，读数据加读锁
        RLock rLock = lock.writeLock();
        rLock.lock();
        try {
            System.out.println("写锁成功。。。"+Thread.currentThread().getName());
            s = UUID.randomUUID().toString();
            Thread.sleep(10000);
            redisTemplate.opsForValue().set("write",s);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            System.out.println("写锁释放。。。"+Thread.currentThread().getName());
            rLock.unlock();
        }

        return s;
    }

    @ResponseBody
    @GetMapping("/read")
    public String readValue(){
        RReadWriteLock lock = redissonClient.getReadWriteLock("rw-lock");
        RLock rLock = lock.readLock();
        rLock.lock();
        String s = "";
        try {
            System.out.println("读锁成功。。。"+Thread.currentThread().getName());
            s = redisTemplate.opsForValue().get("write");
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            System.out.println("读锁释放。。。"+Thread.currentThread().getName());
            rLock.unlock();
        }
        return s;
    }

    @ResponseBody
    @GetMapping("/lockDoor")
    public String lockDoor(){
        RCountDownLatch door = redissonClient.getCountDownLatch("door");
        door.trySetCount(3);
        try {
            door.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "锁门";
    }

    @ResponseBody
    @GetMapping("/go/{id}")
    public String go(@PathVariable("id") Long id){
        RCountDownLatch door = redissonClient.getCountDownLatch("door");
        door.countDown();
        return id+"走了";
    }

    @ResponseBody
    @GetMapping("/park")
    public String park(){
        RSemaphore park = redissonClient.getSemaphore("park");
        try {
            // 信号量-1，空余资源-1
            park.acquire();

        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "ok";
    }

    @ResponseBody
    @GetMapping("/up")
    public String up(){
        RSemaphore park = redissonClient.getSemaphore("park");
        try {
            // 信号量+1，空余资源+1
            park.release();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "ok";
    }
}
